package com.irdstudio.efp.batch.service.impl.dw;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.gdrcu.efp.cus.common.CusStatusEnum;
import com.gdrcu.efp.cus.common.CusTypeEnum;
import com.irdstudio.basic.framework.core.constant.MonAlrmLvlEnums.MonAlrmLvlEnum;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.util.DateTool;
import com.irdstudio.basic.framework.core.util.ValidationUtils;
import com.irdstudio.efp.batch.common.constant.BdLoanConstant;
import com.irdstudio.efp.batch.service.facade.dw.BdCusIndivBatchCreateService;
import com.irdstudio.efp.cus.service.facade.CusIndivCreatesResultTempService;
import com.irdstudio.efp.cus.service.facade.CusIndivCreatesTempService;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.cus.service.vo.CusIndivCreatesResultTempVO;
import com.irdstudio.efp.cus.service.vo.CusIndivCreatesTempVO;
import com.irdstudio.efp.cus.service.vo.CusIndivVO;
import com.irdstudio.efp.loan.service.facade.AccoutErroTempService;
import com.irdstudio.efp.loan.service.vo.AccoutErroTempVO;

/**
 * 
 * 二阶段百度数据移植-数据移植-客户信息同步 <br>
 * 根据ODS卸载的客户信息和批量客户建档结果信息同步到网贷系统客户信息 <br>
 * 
 * @author ludayong
 * @since 2019年5月7日 上午9:51:52
 * @version 1.0
 */
@Service("bdCusIndivBatchCreateService")
public class BdCusIndivBatchCreateServiceImpl implements BdCusIndivBatchCreateService {

	private static Logger logger = LoggerFactory.getLogger(BdCusIndivBatchCreateServiceImpl.class);

	@Autowired
	@Qualifier("accoutErroTempService")
	private AccoutErroTempService accoutErroTempService;// 同步文件记录异常信息

	@Autowired
	@Qualifier("cusIndivCreatesTempService")
	private CusIndivCreatesTempService cusIndivCreatesTempService;// 客户建档信息临时表信息

	@Autowired
	@Qualifier("cusIndivCreatesResultTempService")
	private CusIndivCreatesResultTempService cusIndivCreatesResultTempService;// 客户建档结果信息临时表

	@Autowired
	@Qualifier("cusIndivService")
	private CusIndivService cusIndivService;// 客户建档信息

	/**
	 * 
	 * 根据ODS卸载的客户信息和批量客户建档结果信息同步到网贷系统客户信息 <br>
	 * 0.1:ludayong:2019年5月8日 上午11:11:52:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月8日 上午11:11:52
	 * @date 2019年5月8日 上午11:11:52
	 * @version 0.1
	 */
	@Override
	public boolean batchSyncCusIndiv() throws Exception {
		boolean result = false;
		long startTime = System.currentTimeMillis();
		logger.info("同步客户建档信息和批量客户建档结果信息同步到网贷系统客户信息：[" + DateTool.formatDate(new Date(startTime), DateTool.PATTERN_DATETIME) + "]， 处理开始");
		// 可以配置参数
		Integer pageSize = 1000;
		try {
			// 需要新增或者更新的客户信息
			List<CusIndivVO> cusIndivList = null;
			// 分页信息
			CusIndivCreatesTempVO pageInfo = new CusIndivCreatesTempVO();
			// 新增或者修改的客户信息数量
			int num = 0;
			// 页数
			int page = 1;
			// pageSize初始化
			if (pageSize > 0) {
				pageInfo.setSize(pageSize);
			} else {
				pageInfo.setSize(1000);
			}
			// 判断循环次数
			int size = cusIndivCreatesTempService.queryCount();
			String size_msg = "【客户建档信息临时表】数据量：" + size;
			logger.info(size_msg, "message{}");
			int loopCount = (size / pageInfo.getSize()) + 1;

			// 客户建档成功信息转Map
			//Map<String, String> cusIdMap = initCusIndivCusIdMap();

			// 新增或者修改客户信息数量
			int insertOrUpdateNum = 0;
			for (int i = 0; i < loopCount; i++) {
				String page_msg = "【客户建档信息】当前页数：" + pageInfo.getPage() + "，分页大小：" + pageInfo.getSize();
				logger.info(page_msg, "message{}");
				// 分页查询【客户建档信息临时表】 数据
				List<CusIndivCreatesTempVO> tempList = cusIndivCreatesTempService.queryByPage(pageInfo);
				// 初始化需要新增或者更新的客户信息
				cusIndivList = new ArrayList<CusIndivVO>();
				if (Objects.nonNull(tempList) && !tempList.isEmpty()) {
					try {
						for (CusIndivCreatesTempVO cusIndivCreatesTempVO : tempList) {
							// 客户建档成功
							//if (cusIdMap.containsKey(cusIndivCreatesTempVO.getSerNo())) {
								// 需要新增或者更新的客户信息
								CusIndivVO cusIndivVO = initCusIndivInfo(cusIndivCreatesTempVO);
								if (Objects.nonNull(cusIndivVO)) {
									cusIndivList.add(cusIndivVO);
								}
							//}
						}
						// 需要新增或者更新的网贷客户信息
						if (Objects.nonNull(cusIndivList) && !cusIndivList.isEmpty()) {
							insertOrUpdateNum = 0;
							// 新增或者更新网贷客户信息
							insertOrUpdateNum = cusIndivService.insertOrUpdateCusIndiv(cusIndivList);
							if (insertOrUpdateNum < 1) {
								throw new BizException("新增或者更新客户信息表出错，分页页数：" + page);
							}
							// 新增或者修改客户信息数量
							num += insertOrUpdateNum;
						}
					} catch (Exception e) {
						e.printStackTrace();
						String tableName = "cus_indiv";
						String remark = "新增或者更新客户信息表出错，分页页数：" + page;
						String errorMsg = "新增或者更新客户信息表出错，异常信息：" + e.getMessage();
						logger.error(errorMsg);
						// 记录异常信息
						this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
					}
				}
				pageInfo.setPage(++page);
			}
			String num_msg = "【同步客户建档信息和批量客户建档结果信息同步到网贷系统客户信息表】插入或更新数据处理结果:" + num;
			logger.info(num_msg, "message{}");
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "cus_indiv";
			String errorMsg = "同步客户建档信息和批量客户建档结果信息同步到网贷系统客户信息出错";
			String remark = "同步客户建档信息和批量客户建档结果信息同步到网贷系统客户信息出错，错误信息：" + e.getMessage();
			addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			logger.error(remark);
			throw new Exception(remark);
		}
		long endTime = System.currentTimeMillis();
		logger.info("同步客户建档信息和批量客户建档结果信息同步到网贷系统客户信息：[" + DateTool.formatDate(new Date(endTime), DateTool.PATTERN_DATETIME) + "]， 处理结束");
		logger.info("同步客户建档信息和批量客户建档结果信息同步到网贷系统客户信息，耗时：[" + (endTime - startTime) / 1000.0 + "]秒，处理结果[" + result + "]");
		return result;
	}

	/**
	 * 
	 * 初始化客户信息 <br>
	 * 0.1:ludayong:2019年5月11日 下午5:19:25:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月11日 下午5:19:25
	 * @date 2019年5月11日 下午5:19:25
	 * @version 0.1
	 */
	public CusIndivVO initCusIndivInfo(CusIndivCreatesTempVO cusIndivCreatesTempVO) {
		// 需要新增或者修改的客户信息
		CusIndivVO cusIndivVO = new CusIndivVO();
		try {
			if (BdLoanConstant.CUS_CREATES_STATE.equals(cusIndivCreatesTempVO.getState())) {
				// cus_id 客户编号
				cusIndivVO.setCusId(cusIndivCreatesTempVO.getCusId());
				// inner_cus_id 内部客户号
				cusIndivVO.setInnerCusId(cusIndivCreatesTempVO.getCusId());
				// cus_name 客户名称
				cusIndivVO.setCusName(cusIndivCreatesTempVO.getCusName());
				// cus_type 客户类型 110 自然人
				cusIndivVO.setCusType(CusTypeEnum.NATURAL_MAN.getCode());
				try {
					// indiv_sex 性别 从证件信息中获取性别
					String indivSex = ValidationUtils.getSexFromIdNumber(cusIndivCreatesTempVO.getCertCode()).getEnname();
					cusIndivVO.setIndivSex(indivSex);
				} catch (Exception e) {
					String tableName = "cus_indiv";
					String remark = "获取客户性别信息失败，序号[" + cusIndivCreatesTempVO.getSerNo() + "]，客户名称[" + cusIndivCreatesTempVO.getCusName()
							+ "]";
					logger.error(remark);
					// 记录异常信息
					this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), remark, remark);
				}

				// cert_type 证件类型
				cusIndivVO.setCertType(cusIndivCreatesTempVO.getCertType());
				// cert_code 证件号码
				cusIndivVO.setCertCode(cusIndivCreatesTempVO.getCertCode());
				// phone 联系电话
				cusIndivVO.setPhone(cusIndivCreatesTempVO.getPhone());
				// cus_status 客户状态 20正式客户
				cusIndivVO.setCusStatus(CusStatusEnum.OFFICIAL.getCode());
				// fst_app_channel 首次申请渠道
				cusIndivVO.setFstAppChannel(BdLoanConstant.BD_CHANNEL_NO);

				final String createUser = "admin";
				// create_time 创建时间
				cusIndivVO.setCreateTime(DateTool.getCurrentDateTime());
				// last_update_user 最后修改人
				cusIndivVO.setLastUpdateUser(createUser);
				// last_update_time 最后修改时间
				cusIndivVO.setLastUpdateTime(DateTool.getCurrentDateTime());
				return cusIndivVO;
			} else {
				String tableName = "cus_indiv";
				String remark = "客户建档信息，序号[" + cusIndivCreatesTempVO.getSerNo() + "]，客户名称[" + cusIndivCreatesTempVO.getCusName() + "]建档失败";
				logger.error(remark);
				// 记录异常信息
				this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), remark, remark);
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "cus_indiv";
			String remark = "初始化客户信息出错，客户名称：" + cusIndivCreatesTempVO.getCusName();
			String errorMsg = "初始化客户信息出错，异常信息：" + e.getMessage();
			logger.error(errorMsg);
			// 记录异常信息
			this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
			return null;
		}
	}

	/**
	 * 
	 * 初始化客户ID信息 <br>
	 * 0.1:ludayong:2019年5月11日 下午5:19:25:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月11日 下午5:19:25
	 * @date 2019年5月11日 下午5:19:25
	 * @version 0.1
	 */
	public Map<String, String> initCusIndivCusIdMap() {
		// 客户建档结果信息
		CusIndivCreatesResultTempVO cusIndivCreatesResultTempVO = new CusIndivCreatesResultTempVO();
		cusIndivCreatesResultTempVO.setState(BdLoanConstant.CUS_CREATES_STATE);
		// 客户建档成功信息转Map
		Map<String, String> cusIdMap = new HashMap<String, String>();
		try {
			// 客户建档成功信息
			List<CusIndivCreatesResultTempVO> list = cusIndivCreatesResultTempService
					.queryAllCusIndivCreatesResultInfoWithState(cusIndivCreatesResultTempVO);
			if (Objects.nonNull(list) && !list.isEmpty()) {
				cusIdMap = list.stream()
						.collect(Collectors.toMap(CusIndivCreatesResultTempVO::getSerNo, CusIndivCreatesResultTempVO::getCusId));
			}
		} catch (Exception e) {
			e.printStackTrace();
			String tableName = "cus_indiv";
			String remark = "客户建档成功信息转Map出错";
			String errorMsg = "客户建档成功信息转Map出错，异常信息：" + e.getMessage();
			logger.error(errorMsg);
			// 记录异常信息
			this.addErrorInfo(tableName, MonAlrmLvlEnum.SERIOUS.getEnname(), errorMsg, remark);
		}
		return cusIdMap;
	}

	/**
	 * 
	 * 记录异常信息 <br>
	 * 0.1:ludayong:2019年5月7日 上午11:31:23:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 上午11:31:23
	 * @date 2019年5月7日 上午11:31:23
	 * @version 0.1
	 */
	private void addErrorInfo(String tableName, String errorType, String errorMsg, String remark) {
		AccoutErroTempVO accoutErroTempVO = new AccoutErroTempVO();
		// 表名
		accoutErroTempVO.setTableName(tableName);
		// 错误级别
		accoutErroTempVO.setErroType(errorType);
		// 错误信息
		accoutErroTempVO.setErroMsg(errorMsg);
		// 备注
		accoutErroTempVO.setRemark(remark);
		// 创建时间
		accoutErroTempVO.setCreateData(DateTool.getCurrentDateTime());
		// 修改时间
		accoutErroTempVO.setLastModifyTime(DateTool.getCurrentDateTime());
		// 记录异常信息
		accoutErroTempService.insert(accoutErroTempVO);
	}
}
